#include <windows.h>
#include "MySQL/mysql.h"

#include "CConsole.h"
#include "CDb.h"
#include "CMobHandler.h"
#include "CBasicPacket.h"
#include "CNpc.h"
#include "CZoneHandler.h"
#include "CSpawnMobPool.h"


#include <string>
using namespace std;

CMobHandler * CMobHandler::_instance = NULL;

CMobHandler::CMobHandler() {

}

CMobHandler::~CMobHandler() {

}

CMobHandler * CMobHandler::getInstance() {

	if(_instance == NULL) {
		_instance = new CMobHandler();
	}
	return _instance;
}

void CMobHandler::loadMobPool() {

	MYSQL* mysqlConn;
	int count;
	char query[4096];

	MYSQL_RES * res;
	MYSQL_ROW row;


	int oldzone = 0;
	int oldpoolid = 0;

	memset(query,0,4096);


	strcpy(query, " SELECT *, ((mobid>>12)&255) as zone FROM `pool_mobids` as idpool LEFT JOIN pool_mobs2 as mobinfo ON (mobinfo.poolid=idpool.poolid) LEFT JOIN family_system AS famsys ON (mobinfo.familyId=famsys.familyID) ORDER BY ((mobid>>12)&255), idpool.poolid");

	count = (int) strlen(query);

	mysqlConn=CDb::getConn(); //get conn
	mysql_real_query(mysqlConn, query, count);

	res = mysql_store_result(mysqlConn);
	CDb::pushConn(mysqlConn); //release conn


	if( (res!=NULL) && (mysql_num_rows(res) > 0) )
	{

		mobPoolEntry* entry = NULL;
		unsigned char zone = 0;
		while((row = mysql_fetch_row(res)))
		{
	
	//		poolid 	mobid 	poolid 	name 	familyid 	modelid 	name_prefix 6
	//      flag 	unknown 	cmbSkill 	rcmbSkill 	mJob 	sJob 	cmbDelay 13
	//      rcmbDelay 	behavior 	agressive 	links	mobType Family 	System 	20
	//		FamilyID 	Addsize 	SystemID 	STR 	DEX 	VIT 	AGI 	INT 
	//		MND 	CHR 	EVA 	DEF 	Slash 	Pierce 	H2H 	Impact 	Range 	Fire
	//		Ice 	Wind 	Earth 	Lightning 	Water 	Light 	Dark 	zone	
			int poolid = atoi(row[0]);
			int mobid  = atoi(row[1]);
			char name[30];
			memset(name,0,30);
			memcpy(name,row[3], strlen(row[3]));

			int look;
			memcpy(&look, row[5], 4);
			int name_pre = atoi(row[6]);
			int flag = atoi(row[7]);
			short unknown = atoi(row[8]);



			zone = atoi(row[46]);
			unsigned short addsize = 0;
			if(row[22] != NULL) {
				addsize = atoi(row[22]);
			}
			unsigned int behaviour = atoi(row[15]);
			bool isAgressive = ((atoi(row[16]) == 1 ? true : false));

			
			if ((entry == NULL) || (oldpoolid != poolid) || (zone != oldzone)) 
			{

				if ((entry!=NULL) && ( entry->idPool.size() > 0 )) 
				{
					this->m_mobPool[oldzone].push_back(entry);
				}

				
				entry = new mobPoolEntry();
				entry->mobType = atoi(row[18]);
				memset(entry->name,0,30);
				memset(entry->lookDyn,0,20);
				entry->familyId = atoi(row[4]);
				entry->behaviour = behaviour;
				entry->isAgressive = isAgressive;
				entry->mainJob = atoi(row[11]);
				entry->subJob = atoi(row[12]);
				entry->delay = atoi(row[13]);

				//STR 	DEX 	VIT 	AGI 	INT 	MND 	CHR 	EVA 	DEF 	
				entry->famRank.str = atoi(row[24]);
				entry->famRank.dex = atoi(row[25]);
				entry->famRank.vit = atoi(row[26]);
				entry->famRank.agi = atoi(row[27]);
				entry->famRank.inte = atoi(row[28]);
				entry->famRank.mnd = atoi(row[29]);
				entry->famRank.chr = atoi(row[30]);
				entry->famRank.eva = atoi(row[31]);
				entry->famRank.def = atoi(row[32]);


				entry->intid	= poolid;
				entry->name_pre	= name_pre;
				entry->flag		= flag;
				entry->unknown	= unknown;
				entry->addsize  = addsize;
				memcpy(entry->name, name, strlen(name));
				memcpy(&entry->lookMod, &look, 4);

				mobIDPoolEntry * idEntry = new mobIDPoolEntry();
				idEntry->mobid = mobid;
				idEntry->pMob = NULL;
				idEntry->pInfo = new eInfo();
				idEntry->pInfo->groupId = 0;
				idEntry->pInfo->isAlive = false;
				entry->idPool.push_back(idEntry);

				oldpoolid = poolid;
				oldzone = zone;
			} 
			else 
			{
				mobIDPoolEntry * idEntry = new mobIDPoolEntry();
				idEntry->mobid = mobid;
				idEntry->pMob = NULL;
				idEntry->pInfo = new eInfo();
				idEntry->pInfo->groupId = 0;
				idEntry->pInfo->isAlive = false;
				entry->idPool.push_back(idEntry);
			}
		}

		if ((entry!=NULL) && ( entry->idPool.size() > 0 )) 
			this->m_mobPool[zone].push_back(entry);
	}
	if (res!=NULL)
		mysql_free_result(res);
	

}

unsigned int CMobHandler::getAndAssignFreeId(int poolid, char * name, unsigned short zone, CNpc * npc) {

	for(unsigned int i = 0; i < this->m_mobPool[zone].size(); i++) {

		if(!strcmp(name,this->m_mobPool[zone].at(i)->name)) {

			for(unsigned int j = 0; j < this->m_mobPool[zone].at(i)->idPool.size(); j++) {

				CConsole::outDebOnly("Check CMOB %x ID %x", this->m_mobPool[zone].at(i)->idPool.at(j)->pMob,this->m_mobPool[zone].at(i)->idPool.at(j)->mobid);
				
				if((this->m_mobPool[zone].at(i)->idPool.at(j)->pMob == NULL)) {

					npc->setId(this->m_mobPool[zone].at(i)->idPool.at(j)->mobid);

					// mob and pool and vice versa
					npc->m_pIdPoolEntry = this->m_mobPool[zone].at(i)->idPool.at(j);
					npc->m_pIdPoolEntry->pMob = npc;
					CConsole::outDebOnly("Assign CMOB %x ID %x", npc->m_pIdPoolEntry->pMob, npc->m_pIdPoolEntry->mobid);

					return npc->m_pIdPoolEntry->mobid;
				}
			}
			CConsole::outDebOnly("No free id found for %s",name);
			return 0;	
		}
	}

	return 0;
}

void CMobHandler::freeId(unsigned int mobid, char * name) {

	unsigned char zone = mobid >> 12;
	for(unsigned int i = 0; i < this->m_mobPool[zone].size(); i++) {
		if(!strcmp(name,this->m_mobPool[zone].at(i)->name)) {
			for(unsigned int j = 0; j < this->m_mobPool[zone].at(i)->idPool.size(); j++) {

				if(this->m_mobPool[zone].at(i)->idPool.at(j)->mobid == mobid) {
					this->m_mobPool[zone].at(i)->idPool.at(j)->pMob = NULL;
					return;
				}


			}
			return;	
		}
	}
}

void CMobHandler::spawnMobScripted(char * name, struct position pos, unsigned char zone, unsigned int owner) {

	for(unsigned int i = 0; i < this->m_mobPool[zone].size(); i++) {

		if(!strcmp(name,this->m_mobPool[zone].at(i)->name)) {
			
			CNpc  * npc = new CNpc();
			CSpawnMobPool * pSMP = this->getSpawnMobPoolFromMobPool(this->m_mobPool[zone].at(i), zone);
			if(pSMP == NULL) {
				return;
			}
			npc->setName(name);
			npc->m_id = 0;
			npc->look = this->m_mobPool[zone].at(i)->lookMod;

			npc->m_id = CMobHandler::getAndAssignFreeId(0, name, zone, npc);
		
			if(npc->m_id == 0) {
				return;
			}

			unsigned char zoneid =  npc->m_id >> 12;

			npc->m_targId = npc->m_id;
			npc->m_targId = (unsigned short)(npc->m_targId << 4) >> 4;

			npc->loc.p = pos;
			npc->ownerId = owner;
			
			
			npc->flag =this->m_mobPool[zone].at(i)->flag;
			npc->status = 1;
			npc->type = 0x0f;
			//npc->loc.p = pSP->m_pos;
			npc->unknown = this->m_mobPool[zone].at(i)->unknown;
			npc->namevis = 0;
			npc->m_namePrefix = this->m_mobPool[zone].at(i)->name_pre;
			npc->m_familyId = this->m_mobPool[zone].at(i)->familyId;
			
			srand(clock());
			int level = pSMP->m_minLevel;
			if(pSMP->m_maxLevel != pSMP->m_minLevel) {
				level = pSMP->m_minLevel + rand()%(pSMP->m_maxLevel-pSMP->m_minLevel);
			}
			
			this->m_mobPool[zone].at(i)->mainJob;
			this->m_mobPool[zone].at(i)->subJob;
			npc->m_jobMain = 1;
			npc->m_lvlMain = level;

			if(this->m_mobPool[zone].at(i)->mainJob <= 20) {
				npc->m_jobMain = this->m_mobPool[zone].at(i)->mainJob;
			} else {
				npc->m_jobMain = 1;
			}

			if(this->m_mobPool[zone].at(i)->subJob <= 20) {
				npc->m_jobSub = this->m_mobPool[zone].at(i)->subJob;
			} else {
				npc->m_jobSub = 1;
			}

			npc->l.race = 0x01;
			npc->m_lvlSub = level/2;

			npc->incombat = false;
			npc->ownerId  = 0;
			npc->oldtime  = 0;
			npc->update   = false; 
			npc->timestamp = 0;

			npc->sizeMod = this->m_mobPool[zone].at(i)->addsize;
			
			
			npc->m_speed = 40;
			npc->m_speedAlt = 40;
			npc->setObjType(OBJ_MOB);

			npc->m_mobType = this->m_mobPool[zone].at(i)->mobType;
			
			npc->setAnimation(0);
			npc->old_p		= npc->loc.p;
			npc->tod		= 0;
			npc->m_walkCnt	= 0;
			npc->status		= 0x01;
			npc->moveState	= 0;
			npc->setZone(zone);
			npc->m_statRank = this->m_mobPool[zone].at(i)->famRank;
			if(this->m_mobPool[zone].at(i)->delay != 0) {
				npc->m_defaultDelay = this->m_mobPool[zone].at(i)->delay;
			} else {
				npc->m_defaultDelay = 280;
			}

			npc->m_mobType = this->m_mobPool[zone].at(i)->mobType;

			if((npc->m_mobType == MOBTYPE_NOTORIOUS) || (npc->m_mobType == MOBTYPE_BATTLEFIELD)) {
				npc->m_isNm = true;
			}

			npc->m_behaviour = this->m_mobPool[zone].at(i)->behaviour;
			npc->m_isAgressive = this->m_mobPool[zone].at(i)->isAgressive;
			npc->m_dropList = pSMP->m_dropId;

			CStats::calcStats(npc);

			npc->calcStats();


			if (npc->m_lvlMain >= 30 && npc->m_lvlMain <= 59) {
				npc->m_maxHp = 880 + 80 * (npc->m_lvlMain-29);
			}

			if (npc->m_lvlMain >= 60) {
				npc->m_maxHp = 3300 + 80 * (npc->m_lvlMain-59);
			}

			npc->h.hp = npc->m_maxHp;
	

			CChar * dummychar = CChar::getCChar(owner, "", 0);
			if(dummychar != NULL) {
				npc->ownerId = dummychar->getId();
				npc->m_pTarget = (CBaseEntity *)dummychar;
				npc->incombat = true;
				npc->update = true;
				npc->setAnimation(1);
				npc->victim = dummychar;
				if(npc->getObjectType() == OBJ_MOB)
					npc->updateEnmity((CBaseEntity *)dummychar, 0,1);
			}

			npc->sendUpdate();
			CZoneHandler::getInstance()->mobZoneList[zone].push_back(npc);
			
			}

		}
}

CSpawnMobPool * CMobHandler::getSpawnMobPoolFromMobPool(mobPoolEntry * pMobPoolEntry, int zone) {
	
	CSpawnMobPool * pSMP = NULL;
	for(int y = 0; y < CZoneHandler::getInstance()->mobSpawnZoneList[zone].size(); y++) {
		for(int x = 0; x < CZoneHandler::getInstance()->mobSpawnZoneList[zone].at(y)->m_pSpawnMobPool.size(); x++) {
			if(CZoneHandler::getInstance()->mobSpawnZoneList[zone].at(y)->m_pSpawnMobPool.at(x)->m_pMobPool == pMobPoolEntry) {
				pSMP = CZoneHandler::getInstance()->mobSpawnZoneList[zone].at(y)->m_pSpawnMobPool.at(x);
			}
		}
	}
	return pSMP;

}

void CMobHandler::tmpSpawn(int poolid, char * name, CChar * schar) {

	for(unsigned int i = 0; i < this->m_mobPool[schar->loc.zone].size(); i++) {

		if(!strcmp(name,this->m_mobPool[schar->loc.zone].at(i)->name)) {

			CSpawnMobPool * pSMP = this->getSpawnMobPoolFromMobPool(this->m_mobPool[schar->loc.zone].at(i), schar->loc.zone);
			if(pSMP == NULL) {
				return;
			}
			
			CNpc * npc = new CNpc();

			npc->setName(name);
			npc->m_id = 0;
			npc->look = this->m_mobPool[schar->loc.zone].at(i)->lookMod;

			CMobHandler::getAndAssignFreeId(0, name, schar->loc.zone, npc);
		
			if(npc->m_id == 0) {
				return;
			}

			unsigned char zoneid =  npc->m_id >> 12;

			npc->m_targId = npc->m_id;

			npc->m_targId = (unsigned short)(npc->m_targId << 4) >> 4;




			npc->flag =this->m_mobPool[schar->loc.zone].at(i)->flag;
			npc->status = 1;
			npc->type = 0x0f;
			//npc->loc.p = pSP->m_pos;
			npc->unknown = this->m_mobPool[schar->loc.zone].at(i)->unknown;
			npc->namevis = 0;
			npc->m_namePrefix = this->m_mobPool[schar->loc.zone].at(i)->name_pre;
			npc->m_familyId = this->m_mobPool[schar->loc.zone].at(i)->familyId;
			
			srand(clock());
			int level = pSMP->m_minLevel;
			if(pSMP->m_maxLevel != pSMP->m_minLevel) {
				level = pSMP->m_minLevel + rand()%(pSMP->m_maxLevel-pSMP->m_minLevel);
			}
			
			this->m_mobPool[schar->loc.zone].at(i)->mainJob;
			this->m_mobPool[schar->loc.zone].at(i)->subJob;
			npc->m_jobMain = 1;
			npc->m_lvlMain = level;

			if(this->m_mobPool[schar->loc.zone].at(i)->mainJob <= 20) {
				npc->m_jobMain = this->m_mobPool[schar->loc.zone].at(i)->mainJob;
			} else {
				npc->m_jobMain = 1;
			}

			if(this->m_mobPool[schar->loc.zone].at(i)->subJob <= 20) {
				npc->m_jobSub = this->m_mobPool[schar->loc.zone].at(i)->subJob;
			} else {
				npc->m_jobSub = 1;
			}

			npc->l.race = 0x01;
			npc->m_lvlSub = level/2;

			npc->incombat = false;
			npc->ownerId  = 0;
			npc->oldtime  = 0;
			npc->update   = false; 
			npc->timestamp = 0;

			npc->sizeMod = this->m_mobPool[schar->loc.zone].at(i)->addsize;
			
			
			npc->loc.p = schar->loc.p;
			
			npc->m_speed = 40;
			npc->m_speedAlt = 40;
			npc->setObjType(OBJ_MOB);

			npc->m_mobType = this->m_mobPool[schar->loc.zone].at(i)->mobType;
			
			npc->setAnimation(0);
			npc->old_p		= npc->loc.p;
			npc->tod		= 0;
			npc->m_walkCnt	= 0;
			npc->status		= 0x01;
			npc->moveState	= 0;
			npc->setZone(schar->getZone());
			npc->m_statRank = this->m_mobPool[schar->loc.zone].at(i)->famRank;
			if(this->m_mobPool[schar->loc.zone].at(i)->delay != 0) {
				npc->m_defaultDelay = this->m_mobPool[schar->loc.zone].at(i)->delay;
			} else {
				npc->m_defaultDelay = 280;
			}

			npc->m_mobType = this->m_mobPool[schar->loc.zone].at(i)->mobType;

			if((npc->m_mobType == MOBTYPE_NOTORIOUS) || (npc->m_mobType == MOBTYPE_BATTLEFIELD)) {
				npc->m_isNm = true;
			}

			npc->m_behaviour = this->m_mobPool[schar->loc.zone].at(i)->behaviour;
			npc->m_isAgressive = this->m_mobPool[schar->loc.zone].at(i)->isAgressive;
			npc->m_dropList = pSMP->m_dropId;

			CStats::calcStats(npc);

			npc->calcStats();


			if (npc->m_lvlMain >= 30 && npc->m_lvlMain <= 59) {
				npc->m_maxHp = 880 + 80 * (npc->m_lvlMain-29);
			}

			if (npc->m_lvlMain >= 60) {
				npc->m_maxHp = 3300 + 80 * (npc->m_lvlMain-59);
			}

			npc->h.hp = npc->m_maxHp;


			npc->sendUpdate();
			CZoneHandler::getInstance()->mobZoneList[schar->getZone()].push_back(npc);
			

		}

	}



}



void CMobHandler::spawn(int poolid, mobIDPoolEntry * pPE, CSpawnMobPool * pSMP, struct SpawnPoint* pSP) {
	
	CNpc * npc = new CNpc();


	npc->setName(pSMP->m_pMobPool->name);
	npc->m_id = 0;
	npc->look = pSMP->m_pMobPool->lookMod;

	npc->setId(pPE->mobid);

	// link mob and pool and vice versa
	npc->m_pIdPoolEntry = pPE;
	npc->m_pIdPoolEntry->pMob = npc;
		
	if(npc->m_id == 0) {
		return;
	}

	unsigned char zoneid =  npc->m_id >> 12;

	npc->m_targId = npc->m_id;

	npc->m_targId = (unsigned short)(npc->m_targId << 4) >> 4;
			
	npc->flag = pSMP->m_pMobPool->flag;
	npc->status = 1;
	npc->type = 0x0f;
	npc->loc.p = pSP->m_pos;
	npc->unknown = pSMP->m_pMobPool->unknown;
	npc->namevis = 0;
	npc->m_namePrefix = pSMP->m_pMobPool->name_pre;
	npc->m_familyId = pSMP->m_pMobPool->familyId;
	
	srand(clock());
	int level = pSMP->m_minLevel;
	if(pSMP->m_maxLevel != pSMP->m_minLevel) {
		level = pSMP->m_minLevel + rand()%(pSMP->m_maxLevel-pSMP->m_minLevel);
	}
		
	pSMP->m_pMobPool->mainJob;
	pSMP->m_pMobPool->subJob;
	npc->m_jobMain = 1;
	npc->m_lvlMain = level;

	if(pSMP->m_pMobPool->mainJob <= 20) {
		npc->m_jobMain = pSMP->m_pMobPool->mainJob;
	} else {
		npc->m_jobMain = 1;
	}

	if(pSMP->m_pMobPool->subJob <= 20) {
		npc->m_jobSub = pSMP->m_pMobPool->subJob;
	} else {
		npc->m_jobSub = 1;
	}

	npc->l.race = 0x01;
	npc->m_lvlSub = level/2;

	npc->incombat = false;
	npc->ownerId  = 0;
	npc->oldtime  = 0;
	npc->update   = false; 
	npc->timestamp = 0;

	npc->sizeMod = pSMP->m_pMobPool->addsize;
	npc->m_dropList = pSMP->m_dropId;

	npc->m_speed = 40;
	npc->m_speedAlt = 40;
	npc->setObjType(OBJ_MOB);



	npc->setAnimation(0);
	npc->old_p		= npc->loc.p;
	npc->tod		= 0;
	npc->m_walkCnt	= 0;
	npc->status		= 0x01;
	npc->moveState	= 2;
	npc->setZone(zoneid);
	npc->m_statRank = pSMP->m_pMobPool->famRank;
	if(pSMP->m_pMobPool->delay != 0) {
		npc->m_defaultDelay = pSMP->m_pMobPool->delay;
	} else {
		npc->m_defaultDelay = 280;
	}

	npc->m_mobType = pSMP->m_pMobPool->mobType;

	if((npc->m_mobType == MOBTYPE_NOTORIOUS) || (npc->m_mobType == MOBTYPE_BATTLEFIELD)) {
		npc->m_isNm = true;
	}

	npc->m_behaviour = pSMP->m_pMobPool->behaviour;
	npc->m_isAgressive = pSMP->m_pMobPool->isAgressive;

	CStats::calcStats(npc);

	npc->calcStats();


	if (npc->m_lvlMain >= 30 && npc->m_lvlMain <= 59) {
		npc->m_maxHp = 880 + 80 * (npc->m_lvlMain-29);
	}

	if (npc->m_lvlMain >= 60) {
		npc->m_maxHp = 3300 + 80 * (npc->m_lvlMain-59);
	}

	
	if(strcmp("Tiamat",npc->getName()) == 0) {
		npc->m_maxHp = 120000;
	} else if(strcmp("Vrtra",npc->getName()) == 0) {
		npc->m_maxHp = 100000;
	} else if(strcmp("Cerberus",npc->getName()) == 0) {
		npc->m_maxHp = 50000;
	} else if(strcmp("Hydra",npc->getName()) == 0) {
		npc->m_maxHp = 70000;
	} else if(strcmp("Khimaira",npc->getName()) == 0) {
		npc->m_maxHp = 60000;
	} else if(strcmp("AbsoluteVirtue",npc->getName()) == 0) {
		npc->m_maxHp = 66000;
	} else if(strcmp("KingArthro",npc->getName()) == 0) {
		npc->m_maxHp = 35000;
	} else if(strcmp("Serket",npc->getName()) == 0) {
		npc->m_maxHp = 50000;
	} else if(strcmp("Roc",npc->getName()) == 0) {
		npc->m_maxHp = 30000;
	} else if(strcmp("Fafnir",npc->getName()) == 0) {
		npc->m_maxHp = 70000;
	} else if(strcmp("Nidhogg",npc->getName()) == 0) {
		npc->m_maxHp = 70000;
	} else if(strcmp("KingBehemoth",npc->getName()) == 0) {
		npc->m_maxHp = 75000;
	} else if(strcmp("Behemoth",npc->getName()) == 0) {
		npc->m_maxHp = 50000;
	} else if(strcmp("Aspidochelone",npc->getName()) == 0) {
		npc->m_maxHp = 60000;
	} else if(strcmp("Adamantoise",npc->getName()) == 0) {
		npc->m_maxHp = 40000;
	} else if(strcmp("Medusa",npc->getName()) == 0) {
		npc->m_maxHp = 100000;
	}


	npc->h.hp = npc->m_maxHp;
	
	npc->h.hpp= 100;

	npc->sendUpdate();
	
	pSP->m_pMob = npc;
	npc->m_pSP = pSP;
	npc->m_pIdPoolEntry->tod = 0;
	npc->m_pIdPoolEntry->pInfo->isAlive = true;
	npc->m_pIdPoolEntry->pInfo->groupId = pSP->m_groupId;
	CZoneHandler::getInstance()->mobZoneList[zoneid].push_back(npc);

}


mobIDPoolEntry * CMobHandler::getNextMobId(mobPoolEntry * mPE, unsigned short respawnTime, unsigned int groupId , unsigned short maxSpawns) {


	unsigned short curr = 0;


	if (mPE == NULL) {
		return NULL;
	}

	for(unsigned int i = 0; i < mPE->idPool.size(); i++) {
		if(curr == maxSpawns) {
			return NULL;
		}

		if((mPE->idPool.at(i)->pInfo->isAlive == true) && mPE->idPool.at(i)->pInfo->groupId == groupId ){
			curr++;
			continue;
		}

		if((mPE->idPool.at(i)->pInfo->isAlive == false && mPE->idPool.at(i)->pInfo->groupId == groupId) && ( (time(NULL) - mPE->idPool.at(i)->tod) > respawnTime )){

			return mPE->idPool.at(i);

		}

		if((mPE->idPool.at(i)->pInfo->isAlive == false && mPE->idPool.at(i)->pInfo->groupId == groupId) && ( (time(NULL) - mPE->idPool.at(i)->tod) < respawnTime )){
			curr++;
			continue;
		}

	}

	curr = 0;
	for(unsigned int i = 0; i < mPE->idPool.size(); i++) {
		if(mPE->idPool.at(i)->pInfo->groupId == groupId) {
			curr++;
		}
	}
	
	if(curr == maxSpawns) {
		return NULL;
	}


	for(unsigned int i = 0; i < mPE->idPool.size(); i++) {

		if(mPE->idPool.at(i)->pInfo->isAlive == false && (mPE->idPool.at(i)->pInfo->groupId == 0) && mPE->idPool.at(i)->tod == 0){
			return mPE->idPool.at(i);
		}
	}

	return NULL;

}

